

const puppeteer = require('puppeteer-core');

async function sleep(ms) {
  await new Promise(resolve => setTimeout(resolve, ms));
}

async function crawlPage({url, maxRetries,root, checkResponse, page, browser, attempt = 1} ) {

  try {
    console.log(`Attempt ${attempt} to load ${url}`);

    let responseValids = [];

    page.on('response', async response => {
      
      const url = response.url();
      const status = response.status();
      
      // 自定义响应检查逻辑
      if (checkResponse(response)) {
        responseValids.push(true)
      } else {
        console.warn(`Invalid response from ${url} with status ${status}`);
        responseValids.push(false);
      }
    });

    // 设置超时选项
    await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
    
    await sleep(5000)
    
    // 等待特定的动态内容加载
    await page.waitForSelector(`#${root} div`, { timeout: 15000 });
    
    // 检查是否所有响应都有效
    if (!responseValids.includes(false)) {
      console.log(`Page loaded successfully on attempt ${attempt}`);

      // 页面加载完成后的操作
      // 获取指定 DOM 节点的内容
      const content = await page.evaluate((rootId) => document.getElementById(rootId).innerHTML, root);

      await browser.close();
      return content;
    } else {
      throw new Error('Invalid responses received');
    }
  } catch (error) {
    console.error(`Error on attempt ${attempt}: ${error.message}`);
    // 检查是否达到最大重试次数
    if (attempt >= maxRetries) {
      console.error('Max retries reached. Throwing error.');
      await browser.close();
      throw new Error(`Failed to load page after ${maxRetries} attempts`);
    } else {
      // 重试前等待一段时间
      await sleep(2000)
      const result = await crawlPage({url, maxRetries,root, checkResponse, page, browser, attempt: attempt + 1});
      return result;
    }
   
  }
}



async function render({url, executablePath,maxRetries = 10, root = 'root'}) {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      '--disable-web-security', // 禁用 Web 安全策略

    ],
    executablePath
  })
  const page = await browser.newPage();
  await page.setViewport({
    width: 1245,
    height: 800
  })

  // 启用请求拦截
  await page.setRequestInterception(true);

  page.on('request', request => {
    // 允许所有请求继续
    request.continue();
  });
 const res = await crawlPage({page, browser,url,maxRetries, root, attempt: 1, checkResponse: response => {
    const type = response.request().resourceType();
    const status = response.status();
  
    return ['script', 'stylesheet', 'xhr', 'fetch', 'document'].includes(type) ? [200, 204, 206, 301, 302, 304, 307].includes(status) : true;
  }})
  return res;
}



exports.render = render;